﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntModApp.EntServices.IoC;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition;

namespace EntModApp.EntServices.MEFServices
{
  public class MEFContainerServiceLocatorAdapter : IServiceLocator
  {
    Lazy<CompositionContainer> lazyContainer;

    public MEFContainerServiceLocatorAdapter(Lazy<CompositionContainer> lazyContainer)
    {
      if (lazyContainer == null) throw new ArgumentNullException("lazyContainer");
      this.lazyContainer = lazyContainer;
    }
    public MEFContainerServiceLocatorAdapter(Func<CompositionContainer> lazyContainer)
      : this(new Lazy<CompositionContainer>(lazyContainer))
    {
    }
    public MEFContainerServiceLocatorAdapter(CompositionContainer container)
      : this(new Lazy<CompositionContainer>(() => container))
    {
    }

    public IEnumerable<TService> GetAllInstances<TService>()
    {
      var container = lazyContainer.Value;
      var result = container.GetExportedValues<TService>();
      return result;
    }

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
      var container = lazyContainer.Value;
      var result = container.GetExports(serviceType, null, null).Select(l => l.Value);
      return result;
    }

    public TService GetInstance<TService>()
    {
      var container = lazyContainer.Value;
      TService result = default(TService);
      try
      {
        result = container.GetExportedValue<TService>();
      }
      catch (ImportCardinalityMismatchException ex)
      {
      }
      return result;
    }

    public TService GetInstance<TService>(string key)
    {
      var container = lazyContainer.Value;
      TService result = default(TService);
      try
      {
        result = container.GetExportedValue<TService>(key);
      }
      catch (ImportCardinalityMismatchException ex)
      {
      }
      return result;
    }

    public object GetInstance(Type serviceType)
    {
      var container = lazyContainer.Value;
      object result = null;
      try
      {
        result = container.GetExports(serviceType, null, null).Select(l => l.Value).Single();
      }
      catch (ImportCardinalityMismatchException ex)
      {
      }
      return result;
    }

    public object GetInstance(Type serviceType, string key)
    {
      var container = lazyContainer.Value;
      object result = null;
      try
      {
        result = container.GetExports(serviceType, null, key).Select(l => l.Value).Single();
      }
      catch (ImportCardinalityMismatchException ex)
      {
      }
      return result;
    }
  }
}
